package com.sc.nft.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.dto.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.AdminShareProfitCollectPointsVO;
import com.sc.nft.entity.vo.ecology.AdminDaoEcologyIncomePageVO;
import com.sc.nft.entity.vo.ecology.AdminShareProfitCollectDetailsVO;
import com.sc.nft.entity.vo.ecology.AdminShareProfitCollectVO;
import com.sc.nft.enums.EcologyIncomeTypeEnum;
import com.sc.nft.enums.UserEcologyHatchCollectionTypeRecordsEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.AdminEcologyDaoIncomeConfService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class AdminEcologyDaoIncomeConfServiceImpl implements AdminEcologyDaoIncomeConfService {

    private final EcologyHatchDaoIncomeConfDao ecologyHatchDaoIncomeConfDao;
    private final DaoIdentityDao daoIdentityDao;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final EcologyHatchShareProfitDao ecologyHatchShareProfitDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final EcologyHatchConfDao ecologyHatchConfDao;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;
    private final NewEcologyHatchShareProfitDao newEcologyHatchShareProfitDao;
    private final ShareProfitDaoPoolDao shareProfitDaoPoolDao;
    private final EcologyHatchMethodCollectionConfDao ecologyHatchMethodCollectionConfDao;
    private final UserEcologyHatchCollectionRecordsDao ecologyHatchCollectionRecordsDao;
    @Override
    public Page<AdminDaoEcologyIncomePageVO> page(String daoName, String dividendIncomeName, Boolean status, Integer pageNo, Integer pageSize) {

        Page<AdminDaoEcologyIncomePageVO> page = ecologyHatchDaoIncomeConfDao.getPage(daoName, dividendIncomeName, status, pageNo, pageSize);
        List<AdminDaoEcologyIncomePageVO> records = page.getRecords();
        for (AdminDaoEcologyIncomePageVO record : records) {
            if (ObjectUtil.isNotNull(record.getHatchCollectionId())){
                DigitalCollection digitalCollection = digitalCollectionDao.getById(record.getHatchCollectionId());
                record.setHatchCollectionName(digitalCollection.getFirstTitle());
            }
        }
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addConf(EcologyHatchDaoIncomeConf ecologyHatchDaoIncomeConf) {
        if(ecologyHatchDaoIncomeConf.getDaoIncomeType() != EcologyIncomeTypeEnum.DAO_POSITION_BONUS_AWARD){
            Assert.isTrue(ecologyHatchDaoIncomeConf.getDirectThrustUserCount()>0,()-> new GlobalRunTimeException("推荐人数必须大于0"));
        }else{
            Assert.notNull(ecologyHatchDaoIncomeConf.getHoldCollectionId(),()-> new GlobalRunTimeException("持有的藏品id(持仓奖)不能为空"));
            DigitalCollection digitalCollection = digitalCollectionDao.getById(ecologyHatchDaoIncomeConf.getHoldCollectionId());
            Assert.notNull(digitalCollection,()-> new GlobalRunTimeException("持有的藏品id(持仓奖)不存在"));
            ecologyHatchDaoIncomeConf.setHoldCollectionName(digitalCollection.getFirstTitle());

            /*Assert.isTrue(ecologyHatchDaoIncomeConfDao.getExistIncomeByDaoIdAndCollectionIdAndIncomeTypeAndDimensionality(ecologyHatchDaoIncomeConf.getDaoId()
                    ,ecologyHatchDaoIncomeConf.getDaoIncomeType(),null,ecologyHatchDaoIncomeConf.getCollectionId()),()-> new GlobalRunTimeException("该DAO已存在该类型的收益配置"));*/

        }
        Boolean existIncomeByDaoIdAndHatchCollectionIdNotId = ecologyHatchDaoIncomeConfDao.getExistIncomeByDaoIdAndHatchCollectionIdNotId(ecologyHatchDaoIncomeConf.getId(), ecologyHatchDaoIncomeConf.getDaoId()
                , ecologyHatchDaoIncomeConf.getHatchCollectionId(),ecologyHatchDaoIncomeConf.getDaoIncomeType());
        if (existIncomeByDaoIdAndHatchCollectionIdNotId){
            throw new GlobalRunTimeException("该DAO已存在该熔炼藏品的收益配置");
        }
        Assert.isTrue(NumberUtil.isGreater(ecologyHatchDaoIncomeConf.getIncomeScale().movePointLeft(2), BigDecimal.ZERO),()-> new GlobalRunTimeException("收益比例不能小于0%"));
        Assert.isTrue(NumberUtil.isLessOrEqual(ecologyHatchDaoIncomeConf.getIncomeScale().movePointLeft(2),BigDecimal.ONE),()-> new GlobalRunTimeException("收益比例不能大于100%"));
        Assert.isTrue(EcologyIncomeTypeEnum.getDaoIncomeList().contains(ecologyHatchDaoIncomeConf.getDaoIncomeType()),()-> new GlobalRunTimeException("DAO分润类型错误"));

//        DaoIdentity daoIdentity = daoIdentityDao.getById(ecologyHatchDaoIncomeConf.getDaoIdentityId());
//        Assert.notNull(daoIdentity,()-> new GlobalRunTimeException("DAO身份不存在"));

        DigitalCollection collection = digitalCollectionDao.getById(ecologyHatchDaoIncomeConf.getCollectionId());
        Assert.notNull(collection,()-> new GlobalRunTimeException("藏品不存在"));


        UserCreatorInfo dao = userCreatorInfoDao.getById(ecologyHatchDaoIncomeConf.getDaoId());
        Assert.notNull(dao,()-> new GlobalRunTimeException("DAO不存在"));


        Assert.isTrue(ecologyHatchDaoIncomeConfDao.getExistIncomeByDaoIdAndCollectionIdAndIncomeTypeAndDimensionality(ecologyHatchDaoIncomeConf.getDaoId(),ecologyHatchDaoIncomeConf.getDaoIncomeType(),ecologyHatchDaoIncomeConf.getDimensionality(),ecologyHatchDaoIncomeConf.getCollectionId())
                ,()-> new GlobalRunTimeException("该DAO已存在该类型的收益配置"));

        //判断此DAO和藏品的收益比例
        BigDecimal sumIncomeScale = ecologyHatchDaoIncomeConfDao.getSumIncomeScaleByDaoIdAndDaoIdentityId(ecologyHatchDaoIncomeConf.getDaoId(),ecologyHatchDaoIncomeConf.getHatchCollectionId());
        Assert.isTrue(NumberUtil.isLessOrEqual(sumIncomeScale.add(ecologyHatchDaoIncomeConf.getIncomeScale()).movePointLeft(2), BigDecimal.ONE),()-> new GlobalRunTimeException("DAO收益总比例不能超出100%"));
        BigDecimal sumIncomeScale_ = sumIncomeScale.add(ecologyHatchDaoIncomeConf.getIncomeScale());
        ecologyHatchDaoIncomeConf.setCollectionId(collection.getId());
        ecologyHatchDaoIncomeConf.setDaoName(dao.getDaoName());
        ecologyHatchDaoIncomeConf.setStatus(Boolean.FALSE);
        ecologyHatchDaoIncomeConf.insert();
        BigDecimal sumIncomeScaleTen = sumIncomeScale_.movePointLeft(2);
        BigDecimal incomeScaleBalance = BigDecimal.ONE.subtract(sumIncomeScaleTen);
        List<EcologyHatchDaoIncomeConf> hatchDaoIncomeConfList = ecologyHatchDaoIncomeConfDao.getListByDaoId(ecologyHatchDaoIncomeConf.getDaoId(),ecologyHatchDaoIncomeConf.getHatchCollectionId());
        BigDecimal incomeScaleBalance_ = incomeScaleBalance.movePointRight(2);
        //更新所有dao的剩余分红比例
        for (EcologyHatchDaoIncomeConf hatchDaoIncomeConf : hatchDaoIncomeConfList) {
            Assert.isTrue(ecologyHatchDaoIncomeConfDao.updateIncomeScaleBalanceByAndId(hatchDaoIncomeConf.getId(),incomeScaleBalance_),()-> new GlobalRunTimeException("更新失败"));
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateConf(EcologyHatchDaoIncomeConf updateData) {
        EcologyHatchDaoIncomeConf oldEcologyHatchDaoIncomeConf = ecologyHatchDaoIncomeConfDao.getById(updateData.getId());
        Assert.notNull(oldEcologyHatchDaoIncomeConf,()-> new GlobalRunTimeException("收益配置不存在"));

        if(updateData.getDaoIncomeType() != EcologyIncomeTypeEnum.DAO_POSITION_BONUS_AWARD){
            Assert.isTrue(updateData.getDirectThrustUserCount()>0,()-> new GlobalRunTimeException("推荐人数必须大于0"));
        }else{
            Assert.notNull(updateData.getHoldCollectionId(),()-> new GlobalRunTimeException("持有的藏品id(持仓奖)不能为空"));
            DigitalCollection digitalCollection = digitalCollectionDao.getById(updateData.getHoldCollectionId());
            Assert.notNull(digitalCollection,()-> new GlobalRunTimeException("持有的藏品id(持仓奖)不存在"));
            updateData.setHoldCollectionName(digitalCollection.getFirstTitle());

            /*Assert.isTrue(ecologyHatchDaoIncomeConfDao.getExistIncomeByDaoIdAndCollectionIdAndIncomeTypeAndDimensionality(updateData.getDaoId()
                    ,updateData.getDaoIncomeType(),null,updateData.getCollectionId()),()-> new GlobalRunTimeException("该DAO已存在该类型的收益配置"));*/
        }
        Boolean existIncomeByDaoIdAndHatchCollectionIdNotId = ecologyHatchDaoIncomeConfDao.getExistIncomeByDaoIdAndHatchCollectionIdNotId(updateData.getId(), updateData.getDaoId()
                , updateData.getHatchCollectionId(),updateData.getDaoIncomeType());
        if (existIncomeByDaoIdAndHatchCollectionIdNotId){
            throw new GlobalRunTimeException("该DAO已存在该熔炼藏品的收益配置");
        }
        Assert.isTrue(NumberUtil.isGreater(updateData.getIncomeScale().movePointLeft(2), BigDecimal.ZERO),()-> new GlobalRunTimeException("收益比例不能小于0%"));
        Assert.isTrue(NumberUtil.isLessOrEqual(updateData.getIncomeScale().movePointLeft(2),BigDecimal.ONE),()-> new GlobalRunTimeException("收益比例不能大于100%"));
        Assert.isTrue(EcologyIncomeTypeEnum.getDaoIncomeList().contains(updateData.getDaoIncomeType()),()-> new GlobalRunTimeException("DAO分润类型错误"));

        updateData.setDaoId(oldEcologyHatchDaoIncomeConf.getDaoId());
        updateData.setDaoName(oldEcologyHatchDaoIncomeConf.getDaoName());

        DigitalCollection collection = digitalCollectionDao.getById(updateData.getCollectionId());
        Assert.notNull(collection,()-> new GlobalRunTimeException("藏品不存在"));


        UserCreatorInfo dao = userCreatorInfoDao.getById(updateData.getDaoId());
        Assert.notNull(dao,()-> new GlobalRunTimeException("DAO不存在"));


        if(oldEcologyHatchDaoIncomeConf.getDaoIncomeType() != updateData.getDaoIncomeType()){//如果一致 则直接修改
            Assert.isTrue(ecologyHatchDaoIncomeConfDao.getExistIncomeByDaoIdAndCollectionIdAndIncomeTypeAndDimensionality(updateData.getDaoId(),updateData.getDaoIncomeType(),updateData.getDimensionality(),updateData.getDaoIdentityId())
                    ,()-> new GlobalRunTimeException("该DAO已存在该类型的收益配置"));
        }

        //判断此DAO和藏品的收益比例
        BigDecimal sumIncomeScale = ecologyHatchDaoIncomeConfDao.getSumIncomeScaleByDaoIdAndDaoIdentityId(updateData.getDaoId(),updateData.getHatchCollectionId());
        //此DAO下面所有收益集合 - 旧的收益比例 + 新的收益比例
        //不能超过100
        BigDecimal sumScale = sumIncomeScale.subtract(oldEcologyHatchDaoIncomeConf.getIncomeScale()).add(updateData.getIncomeScale());

        Assert.isTrue(NumberUtil.isLessOrEqual(sumScale.movePointLeft(2), BigDecimal.ONE),()-> new GlobalRunTimeException("DAO收益总比例不能超出100%"));
        Assert.isTrue(NumberUtil.isGreater(sumScale.movePointRight(2),BigDecimal.ZERO),()-> new GlobalRunTimeException("DAO收益总比例不能小于0%"));
        Assert.isTrue(ecologyHatchDaoIncomeConfDao.updateConfById(updateData),()-> new GlobalRunTimeException("更新失败"));
        BigDecimal sumScale_ = sumScale.movePointLeft(2);
        BigDecimal incomeScaleBalance = BigDecimal.ONE.subtract(sumScale_);
        //此Dao所有配置
        List<EcologyHatchDaoIncomeConf> hatchDaoIncomeConfList = ecologyHatchDaoIncomeConfDao.getListByDaoId(updateData.getDaoId(),updateData.getHatchCollectionId());
        BigDecimal incomeScaleBalance_ = incomeScaleBalance.movePointRight(2);
        //更新所有dao的剩余分红比例
        for (EcologyHatchDaoIncomeConf hatchDaoIncomeConf : hatchDaoIncomeConfList) {
            Assert.isTrue(ecologyHatchDaoIncomeConfDao.updateIncomeScaleBalanceByAndId(hatchDaoIncomeConf.getId(),incomeScaleBalance_),()-> new GlobalRunTimeException("更新失败"));
        }
    }

    @Override
    public AdminShareProfitCollectVO shareProfitCollect(Long collectionId) {
        AdminShareProfitCollectVO adminShareProfitCollectVO = new AdminShareProfitCollectVO();
        CollectionBasicsInfoDTO basicsInfo = digitalCollectionDao.getBasicsInfoById(collectionId);
        adminShareProfitCollectVO.setCollectionId(basicsInfo.getCollectionId());
        adminShareProfitCollectVO.setCollectionName(basicsInfo.getCollectionName());
        adminShareProfitCollectVO.setDaoName(basicsInfo.getDaoName());


        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getOneByCollectionId(collectionId);
        Assert.notNull(ecologyHatchConf,()-> new GlobalRunTimeException("生态铸造配置不存在"));
        if(ecologyHatchConf.getDestroyCount() >0){
            Integer count = userEcologyHatchRecordsDao.getcountByCollectionId(collectionId);
            adminShareProfitCollectVO.setDestroyCount(count * ecologyHatchConf.getDestroyCount());
        }
        adminShareProfitCollectVO.setUseCount(userEcologyHatchRecordsDao.getSumUserCount(collectionId));
        adminShareProfitCollectVO.setEcologyPoints(userEcologyHatchRecordsDao.getSumEcologyPointsByCollectionId(collectionId));
        adminShareProfitCollectVO.setDto(ecologyHatchShareProfitDao.getSumDistributionPointsGroupTypeByCollectionId(collectionId));
        return adminShareProfitCollectVO;
    }

    @Override
    public Page<AdminShareProfitCollectDetailsVO> shareProfitCollectDetails(Long collectionId,String userTel, Date startTime, Date endTime, Integer pageNo, Integer pageSize) {
        Page<AdminShareProfitCollectDetailsVO> page = userEcologyHatchRecordsDao.getPageByUserTelAndTime(collectionId,userTel, startTime, endTime, pageNo, pageSize);
        for (AdminShareProfitCollectDetailsVO record : page.getRecords()) {
            record.setDto(ecologyHatchShareProfitDao.shareProfitCollectDetailsByUserRecordId(record.getId()));
        }
        return page;
    }

    @Override
    public void updateStatus(Long id, Boolean status) {
        EcologyHatchDaoIncomeConf ecologyHatchDaoIncomeConf = ecologyHatchDaoIncomeConfDao.getById(id);
        Assert.notNull(ecologyHatchDaoIncomeConf,()-> new GlobalRunTimeException("收益配置不存在"));
        Assert.isTrue(ecologyHatchDaoIncomeConfDao.updateStatusById(id, status),()-> new GlobalRunTimeException("更新失败"));

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteConf(Long id) {
        EcologyHatchDaoIncomeConf conf = ecologyHatchDaoIncomeConfDao.getById(id);
        if (conf.getStatus()){
            throw new GlobalRunTimeException("上架中不可删除");
        }
        Assert.isTrue(ecologyHatchDaoIncomeConfDao.deleteConf(id),()-> new GlobalRunTimeException("更新失败"));
    }



    @Override
    public AdminShareProfitCollectPointsVO shareProfitCollectPoints(Long collectionId) {
        AdminShareProfitCollectPointsVO adminShareProfitCollectPointsVO = new AdminShareProfitCollectPointsVO();
        CollectionBasicsInfoDTO basicsInfo = digitalCollectionDao.getBasicsInfoById(collectionId);
        adminShareProfitCollectPointsVO.setCollectionId(basicsInfo.getCollectionId());
        adminShareProfitCollectPointsVO.setCollectionName(basicsInfo.getCollectionName());
        adminShareProfitCollectPointsVO.setDaoName(basicsInfo.getDaoName());

        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getOneByCollectionId(collectionId);
        Assert.notNull(ecologyHatchConf,()-> new GlobalRunTimeException("生态铸造配置不存在"));
//        if(ecologyHatchConf.getDestroyCount() >0){
        Integer destroyCount = ecologyHatchCollectionRecordsDao.getNumByTypeAndHatchId(UserEcologyHatchCollectionTypeRecordsEnum.DESTROY,ecologyHatchConf.getId());
        adminShareProfitCollectPointsVO.setDestroyCount(destroyCount);
//        }
        adminShareProfitCollectPointsVO.setDto(newEcologyHatchShareProfitDao.getNewSumDistributionPointsGroupTypeByCollectionId(collectionId));
        adminShareProfitCollectPointsVO.setUseCount(userEcologyHatchRecordsDao.getSumUserCount(collectionId));
        adminShareProfitCollectPointsVO.setEcologyPoints(userEcologyHatchRecordsDao.getSumEcologyPointsByCollectionId(collectionId));
        // 服务中心分账积分
        adminShareProfitCollectPointsVO.setServiceCenterPoints(shareProfitDaoPoolDao.getAmountServiceCentre(ecologyHatchConf.getDaoId(),ecologyHatchConf.getId()));
        return adminShareProfitCollectPointsVO;
    }
}
